//
//  PerformanceMonitor.m
//  RBIOSBase
//
//  Created by ren on 09/11/2017.
//  Copyright © 2017 bryan. All rights reserved.
//

#import "PerformanceMonitor.h"

@interface PerformanceMonitor ()
{
	int timeoutCount;
	CFRunLoopObserverRef observer;
	
	@public
	dispatch_semaphore_t semaphore;
	CFRunLoopActivity activity;
}

@end

@implementation PerformanceMonitor

+ (instancetype)sharedInstance
{
	static id instance = nil;
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		instance = [[self alloc] init];
	});
	return instance;
}

static void runLoopObserverCallBack(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info)
{
	PerformanceMonitor *monitor = (__bridge PerformanceMonitor *)info;
	monitor->activity = activity;
	
	dispatch_semaphore_t semaphore = monitor->semaphore;
	dispatch_semaphore_signal(semaphore);
}

- (void)stop
{
	if (!observer) {
		return;
	}
	
	CFRunLoopRemoveObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
	CFRelease(observer);
	observer = NULL;
}

- (void)start
{
	if (observer) {
		return;
	}
	
	//信号
	semaphore = dispatch_semaphore_create(0);
	
	//注册RunLoop状态观察
	CFRunLoopObserverContext context = {0, (__bridge void*)self, NULL, NULL};
	observer = CFRunLoopObserverCreate(kCFAllocatorDefault,
									   kCFRunLoopAllActivities,
									   YES,
									   0,
									   &runLoopObserverCallBack,
									   &context);
	CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
	
	//在子线程监控时长
	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
		while (YES) {
			long st = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, (int64_t)50 * NSEC_PER_MSEC));
			if (st != 0) {
				if (!observer) {
					timeoutCount = 0;
					semaphore = 0;
					activity = 0;
					return ;
				}
				
				if (activity == kCFRunLoopBeforeSources || activity == kCFRunLoopAfterWaiting) {
					if (++timeoutCount < 5) {
						continue;
					}
					NSLog(@"有卡顿了");
				}
			}
			timeoutCount = 0;
		}
	});
	
}

@end
